from dataclasses import dataclass

from fastapi import status
from fastapi.exceptions import HTTPException

from app.controllers.base_controller import BaseController
from app.models.region_models import Region, RegionType
from app.schemas.region_schemas import (CreateRegionTypeSchema,
                                        EditRegionTypeSchema,
                                        GetRegionTypeSchema)


@dataclass
class RegionTypeCreateController(BaseController):
    """Контроллер создания типа региона"""

    request: CreateRegionTypeSchema

    async def execute(self) -> GetRegionTypeSchema:
        if (
            self.request.type is None
            or self.request.type.isspace()
            or self.request.type == ""
        ):
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        regions_with_this_type = await RegionType.filter(type=self.request.type)

        if len(regions_with_this_type) > 0:
            raise HTTPException(status_code=status.HTTP_409_CONFLICT)

        new_region_type = await RegionType.create(type=self.request.type)

        return GetRegionTypeSchema(id=new_region_type.id, type=new_region_type.type)


@dataclass
class GetRegionTypeByIdController(BaseController):
    """Контроллер получения типа региона по ID"""

    type_id: int

    async def execute(self) -> GetRegionTypeSchema:
        if self.type_id is None or self.type_id <= 0:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        region_type = await RegionType.get_or_none(id=self.type_id)

        if region_type is None:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)

        return GetRegionTypeSchema(id=region_type.id, type=region_type.type)


@dataclass
class EditRegionTypeController(BaseController):
    """Контроллер редактирования типа региона"""

    type_id: int
    request: EditRegionTypeSchema

    async def execute(self) -> GetRegionTypeSchema:
        if self.type_id is None or self.type_id <= 0:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        if (
            self.request.type is None
            or self.request.type.isspace()
            or self.request.type == ""
        ):
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        region_type = await RegionType.get_or_none(id=self.type_id)

        if region_type is None:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)

        regions_with_this_type = await RegionType.filter(type=self.request.type)

        if len(regions_with_this_type) > 0:
            raise HTTPException(status_code=status.HTTP_409_CONFLICT)

        region_type.type = self.request.type
        await region_type.save()

        return GetRegionTypeSchema(id=region_type.id, type=region_type.type)


@dataclass
class DeleteRegionTypeController(BaseController):
    """Контроллер удаления региона"""

    type_id: int

    async def execute(self) -> None:
        if self.type_id is None or self.type_id <= 0:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        region_type = await RegionType.get_or_none(id=self.type_id)

        region_with_this_type = await Region.filter(regionType=region_type)
        if len(region_with_this_type) > 0:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        if region_type is None:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)

        await region_type.delete()
